#pragma once

#include <math.h>
#include "Single.h"

namespace BaseType
{

template <typename T> 
T UITCast(const void* ptr) 
{
    union 
    {
        const void* src;
        T dst;
    }data;

    data.src = ptr;
    return data.dst;
}

struct BASE_TYPE_API Numeric
{
    static int32_t NanInt32;

    static int16_t MinInt16;
    static int16_t MaxInt16;
    static uint16_t MaxUint16;

    static int32_t MinInt32;
    static int32_t MaxInt32;
    static uint32_t MaxUint32;

    static int32_t MeasureInt;

    static uint64_t MaxUint64;

public:

    static bool IsNanInt(int32_t x);
    static bool IsMeasureInt(int32_t x);
};

inline bool Numeric::IsNanInt(int32_t x)
{
    return x == NanInt32;
}

class BASE_TYPE_API FloatUtil
{
public:

    static float MinFloat;
    static float MaxFloat;

    static float MaxPrecision;
    static float MinPrecision;

    static float FNaN;
    static float NegInfinity;
    static float PosInfinity;
    static float FloatClosedZero;

    static int Compare(float val1, float val2);
    static bool Equals(float val1, float val2);

    static int FloatToInt(float val);
    static bool IsNaN(float val);
    static bool IsZero(float x);

    static bool IsInfinity(float d);

    static bool IsNegInfinity(float d);
    static bool IsPosInfinity(float d);

    static bool AreClose(float val1, float val2);

    static bool GreaterThan(float val1, float val2);
    static bool GreaterThanOrClose(float val1, float val2);

    static bool LessThan(float val1, float val2);
    static bool LessThanOrClose(float val1, float val2);
};

inline bool FloatUtil::IsNegInfinity(float d)
{
    return (NegInfinity == d);
}

inline bool FloatUtil::IsPosInfinity(float d)
{
    return (PosInfinity == d);
}


}